package com.facepp.demo.util;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;

import java.io.ByteArrayOutputStream;


public class BitmapUtils {


    /**
     * YUV420sp
     *
     * @param inputWidth
     * @param inputHeight
     * @param scaled
     * @return
     */
    public static byte[] getYUV420sp(int inputWidth, int inputHeight,
                                     Bitmap scaled) {

        int[] argb = new int[inputWidth * inputHeight];

        scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

        byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];
        encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

        scaled.recycle();

        return yuv;
    }

    /**
     * RGB转YUV420sp
     *
     * @param yuv420sp
     *            inputWidth * inputHeight * 3 / 2
     * @param argb
     *            inputWidth * inputHeight
     * @param width
     * @param height
     */
    private static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width,
                                       int height) {
        // 帧图片的像素大小
        final int frameSize = width * height;
        // ---YUV数据---
        int Y, U, V;
        // Y的index从0开始
        int yIndex = 0;
        // UV的index从frameSize开始
        int uvIndex = frameSize;

        // ---颜色数据---
        int a, R, G, B;
        //
        int argbIndex = 0;
        //

        // ---循环所有像素点，RGB转YUV---
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {

                // a is not used obviously
                a = (argb[argbIndex] & 0xff000000) >> 24;
                R = (argb[argbIndex] & 0xff0000) >> 16;
                G = (argb[argbIndex] & 0xff00) >> 8;
                B = (argb[argbIndex] & 0xff);
                //
                argbIndex++;

                // well known RGB to YUV algorithm
                Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

                //
                Y = Math.max(0, Math.min(Y, 255));
                U = Math.max(0, Math.min(U, 255));
                V = Math.max(0, Math.min(V, 255));

                // NV21 has a plane of Y and interleaved planes of VU each
                // sampled by a factor of 2
                // meaning for every 4 Y pixels there are 1 V and 1 U. Note the
                // sampling is every other
                // pixel AND every other scanline.
                // ---Y---
                yuv420sp[yIndex++] = (byte) Y;
                // ---UV---
                if ((j % 2 == 0) && (i % 2 == 0)) {
                    //
                    yuv420sp[uvIndex++] = (byte) V;
                    //
                    yuv420sp[uvIndex++] = (byte) U;
                }
            }
        }
    }


        /**
         * 图片的缩放方法
         *
         * @param bitmap  ：源图片资源
         * @param maxSize ：图片允许最大空间  单位:KB
         * @return
         */
        public static Bitmap getZoomImage(Bitmap bitmap, double maxSize) {
            if (null == bitmap) {
                return null;
            }
            if (bitmap.isRecycled()) {
                return null;
            }

            // 单位：从 Byte 换算成 KB
            double currentSize = bitmapToByteArray(bitmap, false).length / 1024;
            // 判断bitmap占用空间是否大于允许最大空间,如果大于则压缩,小于则不压缩
            while (currentSize > maxSize) {
                // 计算bitmap的大小是maxSize的多少倍
                double multiple = currentSize / maxSize;
                // 开始压缩：将宽带和高度压缩掉对应的平方根倍
                // 1.保持新的宽度和高度，与bitmap原来的宽高比率一致
                // 2.压缩后达到了最大大小对应的新bitmap，显示效果最好
                bitmap = getZoomImage(bitmap, bitmap.getWidth() / Math.sqrt(multiple), bitmap.getHeight() / Math.sqrt(multiple));
                currentSize = bitmapToByteArray(bitmap, false).length / 1024;
            }
            return bitmap;
        }

        /**
         * 图片的缩放方法
         *
         * @param orgBitmap ：源图片资源
         * @param newWidth  ：缩放后宽度
         * @param newHeight ：缩放后高度
         * @return
         */
        public static Bitmap getZoomImage(Bitmap orgBitmap, double newWidth, double newHeight) {
            if (null == orgBitmap) {
                return null;
            }
            if (orgBitmap.isRecycled()) {
                return null;
            }
            if (newWidth <= 0 || newHeight <= 0) {
                return null;
            }

            // 获取图片的宽和高
            float width = orgBitmap.getWidth();
            float height = orgBitmap.getHeight();
            // 创建操作图片的matrix对象
            Matrix matrix = new Matrix();
            // 计算宽高缩放率
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // 缩放图片动作
            matrix.postScale(scaleWidth, scaleHeight);
            Bitmap bitmap = Bitmap.createBitmap(orgBitmap, 0, 0, (int) width, (int) height, matrix, true);
            return bitmap;
        }

        /**
         * bitmap转换成byte数组
         *
         * @param bitmap
         * @param needRecycle
         * @return
         */
        public static byte[] bitmapToByteArray(Bitmap bitmap, boolean needRecycle) {
            if (null == bitmap) {
                return null;
            }
            if (bitmap.isRecycled()) {
                return null;
            }

            ByteArrayOutputStream output = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
            if (needRecycle) {
                bitmap.recycle();
            }

            byte[] result = output.toByteArray();
            try {
                output.close();
            } catch (Exception e) {

            }
            return result;
        }
}
